#include "mqtt.h"
#include "json.h"

#define RECONNECT_INTERVAL 5  // 重连间隔（秒）

using namespace std;

int port = 1883;
const char *host = "192.168.123.111";
char is_connect = CONNECT_UNKOWN;

void mosquitto_mqtt_init(struct mosquitto **mosquitto)
{
    int ret;

    ret = mosquitto_lib_init();
    if(ret != MOSQ_ERR_SUCCESS)
    {
        printf("mosquitto_lib_init fail: %s\n", mosquitto_strerror(ret));
    }

    *mosquitto = mosquitto_new("BL10x", true, NULL);
    if(mosquitto == NULL)
    {
        printf("mosquitto_new fail: %s\n", strerror(errno));
        mosquitto_lib_cleanup();
    }
}

void mosquitto_mqtt_connect(struct mosquitto *mosquitto)
{
    int ret = mosquitto_connect(mosquitto, host, port, 30);
    if(ret != MOSQ_ERR_SUCCESS)
    {
        printf("mosquitto_connect fail: %s\n", mosquitto_strerror(ret));
    }
}

int mosquitto_mqtt_publish(struct mosquitto *mosquitto, string &topic, string &message, int qos)
{
    int ret = mosquitto_publish(mosquitto, NULL, topic.c_str(), message.size(), message.c_str(), qos, false);
    if(ret != MOSQ_ERR_SUCCESS)
    {
        printf("mosquitto_publish fail: %s\n", mosquitto_strerror(ret));
    }
    
    return ret;
}

void on_connect(struct mosquitto *mosquitto, void *user_data, int rc)
{
    int ret;

    if(rc != 0)
    {
        printf("connect fail %s\n", mosquitto_strerror(rc));
        is_connect = CONNECT_FAIL;
    }
    else
    {
        printf("connect success\n");
        is_connect = CONNECT_SUCCESS;

        ret = mosquitto_subscribe(mosquitto, NULL, "dest", 0);
        if(ret != MOSQ_ERR_SUCCESS)
        {
            printf("mosquitto_subscribe fail %s\n", mosquitto_strerror(rc));
        }
    }
}

void on_message(struct mosquitto *mosquitto, void *user_data, const struct mosquitto_message *message)
{
    int len = message->payloadlen;
    if(len > 0)
    {
        // printf("receive topic: %s payload: %s\n", message->topic, (char *)message->payload);
        string payload((char *)message->payload, message->payloadlen); //构造函数，根据字符串和字符串参数对string对象进行构造
        rapidjson_parse_json(payload);
    }
}

// 断开连接回调：实现自动重连
void on_disconnect(struct mosquitto *mosquitto, void *user_data, int rc)
{
    if (rc == 0)
    {
        // 主动断开连接，不触发重连
        printf("Disconnected normally\n");
        is_connect = CONNECT_FAIL;  // 更新状态
        return;
    }

    // 意外断开，标记连接状态并启动重连
    printf("Unexpected disconnection (code: %d), trying to reconnect...\n", rc);
    is_connect = CONNECT_FAIL;

    // 重连循环：仅在程序运行时重试
    while (is_connect != CONNECT_SUCCESS)
    {
        printf("Reconnecting in %d seconds...\n", RECONNECT_INTERVAL);
        sleep(RECONNECT_INTERVAL);

        int ret = mosquitto_reconnect(mosquitto);
        if (ret == MOSQ_ERR_SUCCESS)
        {
            printf("Reconnect request sent successfully\n");
            // 注意：这里只是发送了重连请求，实际连接结果由on_connect回调更新
            break;
        }
        else
        {
            printf("Reconnect failed: %s\n", mosquitto_strerror(ret));
        }
    }
}

void mosquitto_mqtt_connect_callback_set(struct mosquitto *mosquitto)
{
    mosquitto_connect_callback_set(mosquitto, on_connect);
}

void mosquitto_mqtt_message_callback_set(struct mosquitto *mosquitto)
{
    mosquitto_message_callback_set(mosquitto, on_message);
}

void mosquitto_mqtt_disconnect_callback_set(struct mosquitto *mosquitto)
{
    mosquitto_disconnect_callback_set(mosquitto, on_disconnect);
}

